package cn.itcast.web.controller.cargo;

import cn.itcast.domain.cargo.Contract;
import cn.itcast.domain.cargo.ContractExample;
import cn.itcast.domain.system.User;
import cn.itcast.service.cargo.ContractProductService;
import cn.itcast.service.cargo.ContractService;
import cn.itcast.service.system.UserService;
import cn.itcast.vo.ContractProductVo;
import cn.itcast.web.controller.BaseController;
import cn.itcast.web.utils.DownloadUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.github.pagehelper.PageInfo;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/cargo/contract")
public class ContractController extends BaseController {
    @Reference
    private ContractService contractService;

    @Reference
    private ContractProductService contractProductService;

    @Autowired
    private UserService userService;

    private DownloadUtil downloadUtil = new DownloadUtil();

    /**
     * url:/cargo.contract/list.do
     * 参数：无
     * 作用：进入购销合同的列表页面
     * 返回值：购销合同的列表
     */
    @RequestMapping("/list")
    public String list(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "5") int pageSize) {
        ContractExample contractExample = new ContractExample();
        //在逆向工程中如果需要根据时间排序，不是条件
        contractExample.setOrderByClause("create_time desc");
        ContractExample.Criteria criteria = contractExample.createCriteria();
        //货物当前登陆者
        User loginUser = getLoginUser();
        //得到登陆者的等级
        Integer degree = loginUser.getDegree();
        if (degree == 4) {
            //普通员工
            criteria.andCreateByEqualTo(loginUser.getId());
        } else if (degree == 3) {
            //部门经理
            criteria.andCreateDeptEqualTo(loginUser.getDeptId());
        } else if (degree == 2) {
            //大区经理
            PageInfo<Contract> pageInfo = contractService.findPageDeptId(loginUser.getCompanyId(), loginUser.getDeptId(), pageNum, pageSize);
            request.setAttribute("pageInfo", pageInfo);
            return "cargo/contract/contract-list";

        } else if (degree == 1) {
            //系统管理员
            criteria.andCompanyIdEqualTo(loginUser.getCompanyId());
        }


        PageInfo<Contract> pageInfo = contractService.findByPage(contractExample, pageNum, pageSize);
        request.setAttribute("pageInfo", pageInfo);
        return "cargo/contract/contract-list";
    }

    /**
     * url:cargo/contract/contract-add
     * 作用：进入添加页面
     * 参数：无
     */
    @RequestMapping("/toAdd")
    public String toAdd() {
        //下拉列表
        User user = userService.findById(getLoginUser().getId());
        ArrayList<User> users = new ArrayList<>();
        if (user.getDegree()==0||user.getDegree()==null){
            users.add(getLoginUser());
        }else {
            users=userService.findDeptDegrr(user.getDeptId(),user.getDegree());
        }
            request.setAttribute("deptUserById",users);
        return "cargo/contract/contract-add";
    }

    /*
  url: cargo/contract/edit.do
  作用： 新增购销合同||更新购销合同
  参数： 购销合同
  返回值：购销合同列表页面
 */
    @RequestMapping("/edit")
    public String edit(Contract contract) {
        //补全购销合同信息
        String companyId = getLoginCompanyId();
        String companyName = getLoginCompanyName();
        contract.setCompanyId(companyId);
        contract.setCompanyName(companyName);
        //补全购销创建人与创建人所属的购销合同
        contract.setCreateBy(getLoginUser().getId()); //登陆者的id
        contract.setCreateDept(getLoginUser().getDeptId()); //登陆者所属的购销合同

        if (StringUtils.isEmpty(contract.getId())) {
            contractService.save(contract);
        } else {
            contractService.update(contract);
        }
        return "redirect:/cargo/contract/list.do";  //添加redirect开头的返回值则不会经过视图解析器
    }


    /*
    url: /system/Contract/toUpdate.do?id=100
    作用： 进入更新购销合同页面
    参数： 购销合同的id
    返回值：购销合同更新页面
   */
    @RequestMapping("/toUpdate")
    public String toUpdate(String id) {
        //1.根据id查询当前购销合同信息
        Contract contract = contractService.findById(id);
        request.setAttribute("contract", contract);
        return "cargo/contract/contract-update";
    }


    /*
    url: /system/Contract//delete.do?id="+id,
    作用： 删除购销合同
    参数： 购销合同的id
    返回值：购销合同列表页面
   */
    @RequestMapping("/delete")
    @ResponseBody
    public Map<String,Object> delete(String id) {
        HashMap<String, Object> result = new HashMap<>();

        Contract contract = contractService.findById(id);
//        String referer = request.getHeader("referer");

        if (contract.getState()==null||contract.getState()==0){
            contractService.delete(id);
//            result.put("referer",referer);
            result.put("message","0");
        }else if (contract.getState()==1){
            result.put("message","1");
        }else if (contract.getState()==2){
            result.put("message","2");
        }

        return result;
    }

    /**
     * url:/cargo/contract/toView.do
     * 作用：查看购销合同
     * 参数：购销合同的id
     */
    @RequestMapping("/toView")
    public String toView(String id) {
        Contract contract = contractService.findById(id);
        request.setAttribute("contract", contract);
        return "cargo/contract/contract-view";

    }

    /*
    url: /cargo/contract/submit.do?id=4bc7ae89-f02c-4cb0-b74b-ef0e4170adb2
    作用： 提交购销合同
    参数： 购销合同的id
    返回值：购销合同列表
*/
    @RequestMapping("/submit")
    public String submit(String id) {
        Contract byId = contractService.findById(id);
        String checkBy = byId.getCheckBy();
        String id1 = getLoginUser().getUserName();
        if (id1.equals(checkBy)) {
            // 创建购销合同对象
            Contract contract = new Contract();
            // 设置id，作为修改条件
            contract.setId(id);
            // 设置状态，修改的值
            contract.setState(1);
            // 修改
            contractService.update(contract);
            // 重定向到列表
            return "redirect:/cargo/contract/list.do";
        } else {
            Contract myContract = contractService.findById(id);
            if (myContract.getState() == 0) {
                Contract contract = new Contract();
                // 设置id，作为修改条件
                contract.setId(id);
                // 设置状态，修改的值
                contract.setState(3);
                // 修改
                contractService.update(contract);
            }


            return "redirect:/cargo/contract/list.do";

        }
    }


    /*
     url: /cargo/contract/cancel.do?id=4bc7ae89-f02c-4cb0-b74b-ef0e4170adb2
     作用： 取消交购销合同
     参数： 购销合同的id
     返回值：购销合同列表
*/
    @RequestMapping("/cancel")
    public String cancel(String id) {
        Contract contract = contractService.findById(id);
        contract.setState(0);
        contractService.update(contract);
        return "redirect:/cargo/contract/list.do";
    }

    /**
     * 使用模板导出需要准备的工作
     * 1.需要提前准备好一个模板，模板内容你自己设置
     * 作用：使用模板导出出货表
     * url:/cargo/contract/printExcel.do
     * 参数：inputDate 出货表的月份
     * 返回：没有返回值，只要求下载出货表 注意：如果需要做文件的下载，使用springmvc的基础上我们需要添加一个@repsonBody
     */
    @RequestMapping("/printExcel")
    @ResponseBody //写出json需要添加，下载文件的时候也选哟添加
    public void printExcel(String inputDate) throws Exception {
        //读取到模板的输入刘
        InputStream inputStream = session.getServletContext().getResourceAsStream("D:\\tOUTPRODUCT.xlsx");

        //模板的输入流交给工作簿
        Workbook workbook = new XSSFWorkbook(inputStream);
        //2.创建工作单
        Sheet sheet = workbook.createSheet("出货表");
        //3. 合并单元格
       /*int firstRow  合并的开始行
          int lastRow   合并的结束行
          int firstCol  合并的开始列
           int lastCol  合并的结束列
         */
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 1, 8));

        //4. 设置列宽
        /*
         参数1： 列的索引值
         参数2： 宽度
         */
        sheet.setColumnWidth(1, 26 * 256);
        sheet.setColumnWidth(2, 14 * 256);
        sheet.setColumnWidth(3, 26 * 256);
        sheet.setColumnWidth(4, 14 * 256);
        sheet.setColumnWidth(5, 14 * 256);
        sheet.setColumnWidth(6, 14 * 256);
        sheet.setColumnWidth(7, 14 * 256);
        sheet.setColumnWidth(8, 14 * 256);

        //操作第0行
        Row row = sheet.createRow(0);
        //获取第0行的第一个单元格
        Cell cell = row.createCell(1);
        //准备标题内容   inputDate = 2019-03 2019-12
        String title = inputDate.replace("-0", "年").replace("-", "年") + "月份出货表";
        //给单元格设置标题内容
        cell.setCellValue(title);
        //标题的样式 ，老师我现在直接使用你的表格的样式，我自己不会写。不用怕，后天我们学习模板导出,一个样式都不需要写
        cell.setCellStyle(bigTitle(workbook));


        //操作表头， 索引值为1的这行
        row = sheet.createRow(1);
        String[] titles = {"客户", "订单号", "货号", "数量", "工厂", "工厂交期", "船期", "贸易条款"};
        for (int i = 0; i < titles.length; i++) {
            //创建单元格
            cell = row.createCell(i + 1);
            cell.setCellValue(titles[i]);
            //设置样式
            cell.setCellStyle(title(workbook));
        }
        //excel的数据内容
        //如果单元格数据是日期类型，那么我们在设置内容之前必须要先格式化
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        //根据船期查询对应的货物的数据
        List<ContractProductVo> contractProductVoList = contractProductService.findByShipTime(getLoginCompanyId(), inputDate);
        //定义一个变量保存开始的行数
        int index = 2;
        for (int i = 0; i < 5847; i++) {
            //遍历所有的货物数据
            for (ContractProductVo contractProductVo : contractProductVoList) {
                //创建行
                row = sheet.createRow(index++);

                //客户
                cell = row.createCell(1);
                if (contractProductVo.getCustomName() != null) {
                    //设置内容
                    cell.setCellValue(contractProductVo.getCustomName());
                    //设置样式

                }


                //客户
                cell = row.createCell(2);
                if (contractProductVo.getContractNo() != null) {
                    //设置内容
                    cell.setCellValue(contractProductVo.getContractNo());
                    //设置样式

                }

                //货物
                cell = row.createCell(3);
                if (contractProductVo.getProductNo() != null) {
                    //设置内容
                    cell.setCellValue(contractProductVo.getProductNo());
                    //设置样式

                }

                //数量
                cell = row.createCell(4);
                if (contractProductVo.getCnumber() != null) {
                    //设置内容
                    cell.setCellValue(contractProductVo.getCnumber());
                    //设置样式

                }

                //工厂
                cell = row.createCell(5);
                if (contractProductVo.getFactoryName() != null) {
                    //设置内容
                    cell.setCellValue(contractProductVo.getFactoryName());
                    //设置样式

                }

                //交货日期
                cell = row.createCell(6);
                if (contractProductVo.getDeliveryPeriod() != null) {
                    //设置内容
                    cell.setCellValue(simpleDateFormat.format(contractProductVo.getDeliveryPeriod()));
                    //设置样式

                }

                //船期
                cell = row.createCell(7);
                if (contractProductVo.getShipTime() != null) {
                    //设置内容
                    cell.setCellValue(simpleDateFormat.format(contractProductVo.getShipTime()));
                    //设置样式

                }


                //贸易条款
                cell = row.createCell(8);
                if (contractProductVo.getTradeTerms() != null) {
                    //设置内容
                    cell.setCellValue(contractProductVo.getTradeTerms());
                    //设置样式

                }

            }
        }
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); //这个类的本质就是一个字节数组
        workbook.write(outputStream);  // 把excel表格内容写入到该流中，其实本质上就是写入到一个数组中

        downloadUtil.download(outputStream, response, "出货表.xlsx");
    }

    //大标题的样式
    public CellStyle bigTitle(Workbook wb) {
        CellStyle style = wb.createCellStyle();
        Font font = wb.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 16);
        font.setBold(true);//字体加粗
        style.setFont(font);
        style.setAlignment(HorizontalAlignment.CENTER);                //横向居中
        style.setVerticalAlignment(VerticalAlignment.CENTER);        //纵向居中
        return style;
    }

    //小标题的样式
    public CellStyle title(Workbook wb) {
        CellStyle style = wb.createCellStyle();
        Font font = wb.createFont();
        font.setFontName("黑体");
        font.setFontHeightInPoints((short) 12);
        style.setFont(font);
        style.setAlignment(HorizontalAlignment.CENTER);                //横向居中
        style.setVerticalAlignment(VerticalAlignment.CENTER);        //纵向居中
        style.setBorderTop(BorderStyle.THIN);                        //上细线
        style.setBorderBottom(BorderStyle.THIN);                    //下细线
        style.setBorderLeft(BorderStyle.THIN);                        //左细线
        style.setBorderRight(BorderStyle.THIN);                        //右细线
        return style;
    }

    //文字样式
    public CellStyle text(Workbook wb) {
        CellStyle style = wb.createCellStyle();
        Font font = wb.createFont();
        font.setFontName("Times New Roman");
        font.setFontHeightInPoints((short) 10);

        style.setFont(font);

        style.setAlignment(HorizontalAlignment.LEFT);                //横向居左
        style.setVerticalAlignment(VerticalAlignment.CENTER);        //纵向居中
        style.setBorderTop(BorderStyle.THIN);                        //上细线
        style.setBorderBottom(BorderStyle.THIN);                    //下细线
        style.setBorderLeft(BorderStyle.THIN);                        //左细线
        style.setBorderRight(BorderStyle.THIN);                        //右细线

        return style;
    }
}

